package com.euond.permission.service.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.euond.common.core.dto.ResultDto;
import com.euond.common.core.dto.SerachMapDto;
import com.euond.common.core.service.impl.BaseServiceImpl;
import com.euond.permission.dto.MenuDto;
import com.euond.permission.entities.Menu;
import com.euond.permission.entities.Resource;
import com.euond.permission.mapper.MenuMapper;
import com.euond.permission.service.MenuService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Created by Daniel on 22/06/2017.Ø
 * Menu service implementation
 */
@Service
public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    MenuMapper menuMapper;

    private Integer pFlag=0;

    /**
     * 按项目、公司获取用户的菜单
     */
    @Override
    public ResultDto findMenus(Long projectId, Long companyId, Long userId) {

        List<Menu> menuList;
        if (userId!=null){
            pFlag=0;
            // 1. 取用户指定的项目菜单，用户登录后主页面的菜单树
            menuList = baseMapper.findUserMenus(projectId, companyId, userId);
        }
        else{
            pFlag=1;
            //菜单管理的菜单树，无需用户权限过滤
            menuList = baseMapper.findUserMenusNoPermission(projectId, companyId);
        }
        // 2. 转换菜单并返回
        ResultDto resultDto=new ResultDto("0","seccess",convertToMenus(menuList));
        return resultDto;
    }

    /**
     * 根据菜单实体列表数据形成菜单树
     */
    public List<MenuDto> convertToMenus(List<Menu> menuList) {

        if (menuList.isEmpty()) {
            return Collections.emptyList();
        }
        // 自动生成一条为ID0记录的根节点，因为任何菜单的第一层的parentId必须为0
         //MenuDto root = convertToMenuDto(menuList.remove(menuList.size() - 1)); 对应原来数据库中必须存在一条根节点记录方式
        MenuDto root=new MenuDto(Long.valueOf("0"), "根节点","", "",1,Long.valueOf("0"),Long.valueOf("0"),"");
        recursiveMenu(root, menuList);
        List<MenuDto> menuDtoList = root.getChildren();
        if(pFlag.equals(0)) {
            removeNoLeafMenu(menuDtoList);
        }
        return menuDtoList;
    }

    /**
     * 去掉没有子模块的菜单项
     */
    private void removeNoLeafMenu(List<MenuDto> menuDtoList) {
        if (menuDtoList.isEmpty()) {
            return;
        }
        for (int i = menuDtoList.size() - 1; i >= 0; i--) {
            MenuDto m = menuDtoList.get(i);
            removeNoLeafMenu(m.getChildren());
            if (!m.isHasChildren() && StringUtils.isEmpty(m.getUrl())) {
                menuDtoList.remove(i);
            }
        }
    }

    /**
     * 根据菜单实体列表数据形成菜单树
     */
    private void recursiveMenu(MenuDto menuDto, List<Menu> menuList) {
        for (int i = menuList.size() - 1; i >= 0; i--) {
            Menu menu = menuList.get(i);
            if (menu.getParentId().equals(menuDto.getId())) {
                menuDto.getChildren().add(convertToMenuDto(menu));
                menuList.remove(i);
            }
        }

        for (MenuDto subMenu : menuDto.getChildren()) {
            recursiveMenu(subMenu, menuList);
        }
    }

    private MenuDto convertToMenuDto(Menu menu) {
        return new MenuDto(menu.getId(), menu.getName(), menu.getIcon(), menu.getUrl(),menu.getSequence(),menu.getResourceId(),menu.getParentId(),menu.getParentIds());
    }

    /**
     * 按项目查找未分配菜单的资源清单
     * @param searchParams
     * @return
     */
    public ResultDto findNotAllotMenuResources(Map<String,Object> searchParams){
        Menu menu=new Menu();
        SerachMapDto serachMapDto=new SerachMapDto(searchParams,menu);
        Page<Resource> page=new Page(serachMapDto.getPageCurrent(),serachMapDto.getPageSize());
        //假如存在需要扩展特殊的条件内容，则可以(UserRole)serachMapDto.getObject()重新赋值
        page.setRecords(menuMapper.findNotAllotMenuResources(page,(Menu)serachMapDto.getObject()));
        ResultDto resultDto=new ResultDto("0","seccess",page.getRecords(),page.getTotal());
        return resultDto;
    }
}
